#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016-2018, Niklas Hauser
# Copyright (c) 2017, Fabian Greif
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

class Instance(Module):
    def __init__(self, instance):
        self.instance = "" if instance is None else instance
        self.peripheral = 1 if instance is None else instance

    def init(self, module):
        module.name = str(self.instance)
        module.description = "Instance {}".format(self.instance)

    def prepare(self, module, options):
        return True

    def build(self, env):
        device = env[":target"]
        driver = device.get_driver("adc")

        properties = {}
        properties["target"] = target = device.identifier
        properties["id"] = self.instance
        properties["per"] = self.peripheral

        # TODO: Consider moving this data to device file!
        properties["temperature_available"] = (target["family"] in ["f2", "f4", "f7"] or
                                              (target["family"] == "f1" and self.instance == 1))
        properties["resolution"] = 12
        properties["max_frequency"] = 36000000 if target["family"] in ["f4", "f7"] else 14000000

        channels = [0,1,2,3,4,5,6,7,8,10,11,12,13]
        if target["family"] in ["f2", "f4", "f7"]:
            channels.extend([9,14,15,16,17,18])
        elif target["family"] in ["f1", "f3"]:
            if self.instance == 1:
                channels.extend([16,17])
            if self.instance < 3:
                channels.extend([9,14,15])
        properties["channels"] = sorted(channels)
        global props
        properties["shared_irq_ids"] = props["shared_irq_ids"]
        properties["irq"] = "1" if target.family in ["l1"] else self.instance
        props["instances"].append(self.instance)

        env.substitutions = properties
        env.outbasepath = "modm/src/modm/platform/adc"

        env.template("adc.hpp.in", "adc_{}.hpp".format(self.instance))
        env.template("adc_impl.hpp.in", "adc_{}_impl.hpp".format(self.instance))
        env.template("adc_interrupt.hpp.in", "adc_interrupt_{}.hpp".format(self.instance))
        env.template("adc_interrupt.cpp.in", "adc_interrupt_{}.cpp".format(self.instance))


def init(module):
    module.name = ":platform:adc"
    module.description = "Analog-to-Digital Converter (ADC)"

def prepare(module, options):
    device = options[":target"]
    if not device.has_driver("adc:stm32"):
        return False
    global props
    props = {}
    driver = device.get_driver("adc")
    props["target"] = target = device.identifier
    props["driver"] = driver
    props["instances"] = []

    if target["family"] in ["f2", "f4", "f7"]:
        props["shared_irqs"] = {"ADC": listify([int(i) for i in device.get_driver("adc")["instance"]])}
        props["shared_irq_ids"] = props["shared_irqs"]["ADC"]
    elif target["family"] in ["u5"]:
        # STM32U5 is not yet supported with any ADC implementation im modm
        return False
    else:
        shared_irqs = [v["name"] for v in device.get_driver("core")["vector"]]
        shared_irqs = [v for v in shared_irqs if v.startswith("ADC") and "_" in v]
        props["shared_irqs"] = {}
        props["shared_irq_ids"] = []
        for irq in shared_irqs:
            parts = irq[3:].split("_")
            shared_irqs_ids = (int(parts[0]), int(parts[1]) )
            props["shared_irqs"][irq] = shared_irqs_ids
            props["shared_irq_ids"].extend(shared_irqs_ids)


    module.depends(
        ":architecture:adc",
        ":architecture:register",
        ":cmsis:device",
        ":platform:gpio",
        ":platform:rcc",
        ":math:algorithm")

    for instance in listify(device.get_driver("adc").get("instance", [])):
        module.add_submodule(Instance(int(instance)))

    return True

def build(env):
    device = env[":target"]
    driver = device.get_driver("adc")

    global props

    env.substitutions = props
    env.outbasepath = "modm/src/modm/platform/adc"

    if device.get_driver("adc").get("instance", None) is None:
        Instance(None).build(env)

    if any(i in props["shared_irq_ids"] for i in props["instances"]):
        env.template("adc_shared_interrupts.cpp.in")
